package br.com.rotary.servico;

import br.com.rotary.enums.Status;
import br.com.rotary.enums.TipoConvidado;
import br.com.rotary.enums.TipoParticipante;
import br.com.rotary.generico.ServicoGenerico;
import br.com.rotary.modelo.Clube;
import br.com.rotary.modelo.FichaInscricao;
import br.com.rotary.modelo.Pessoa;
import java.beans.Transient;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.Query;

/**
 *
 * @author laverson
 */
@Stateless
public class FichaInscricaoServico extends ServicoGenerico<FichaInscricao> {

    private Long quantidadeRegistrosResults;

    public FichaInscricaoServico() {
        super(FichaInscricao.class);
    }

    @Override
    public void remover(FichaInscricao entity) {
        entity.setAtivo(false);
        atualizar(entity);
    }

    public List<Clube> pesquisarClubesCadastrados() {

        String sql = "SELECT distinct c FROM " + FichaInscricao.class.getSimpleName() + " f JOIN f.clube c "
                + "WHERE f.ativo = true";

        Query query = getEntityManager().createQuery(sql);

        return query.getResultList();

    }

    /**
     * Pesquisar FichaInscricao
     *
     * @param pesquisarFichaInscricao
     * @return
     */
    @Override
    public List<FichaInscricao> pesquisar(FichaInscricao entidade, Integer first, Integer pageSize) {

        String select = "select f ";
        String where = "WHERE ";
        String orderBy = "order by f.participante.nome asc";

        String from = "from " + FichaInscricao.class.getSimpleName() + " f ";


        if (entidade.getTipoParticipante() != null) {
            where += "LOWER(f.tipoParticipante) LIKE :tipoParticipante AND ";
        }

        if (entidade.getMeioTransporte() != null) {
            where += "LOWER(f.meioTransporte) LIKE :meioTransporte AND ";
        }

        if (entidade.getTipoConvidado() != null) {
            where += "LOWER(f.tipoConvidado) LIKE :tipoConvidado AND ";
        }

        if (entidade.getStatus() != null) {
            if (entidade.getStatus().equals(Status.PAGO) || entidade.getStatus().equals(Status.PAGO_SEM_FICHA)) {
                where += "LOWER(f.status) LIKE :status AND ";
            }
        }

        if (entidade.getParticipante() != null) {

            Pessoa participante = entidade.getParticipante();

            from += "JOIN f.participante p ";

            if (participante.getNome() != null && !participante.getNome().isEmpty()) {
                where += "LOWER(p.nome) LIKE :nomeParticipante AND ";
            }

            if (participante.getEnderecoSimples() != null && !participante.getEnderecoSimples().isEmpty()) {
                where += "LOWER(p.enderecoSimples) LIKE :enderecoSimples AND ";
            }
        }

        if (entidade.getClube() != null) {

            if (entidade.getClube().getId() != null) {
                from += "JOIN f.clube c ";
                where += "c.id = :clubeId AND ";
            }
        }

        if (entidade.getConvidado() != null) {

            if (entidade.getConvidado().getNome() != null && !entidade.getConvidado().getNome().isEmpty()) {
                from += "JOIN f.convidado co ";
                where += "LOWER(co.nome) LIKE :nomeConvidado AND ";
            }
        }

        where += " f.ativo = true ";

        Query query = getEntityManager().createQuery(select.concat(from).concat(where).concat(orderBy));

        setQuantidadeRegistros(from.concat(where), query, entidade);

        setParameters(entidade, query);

        if (first != null && pageSize != null) {
            query.setFirstResult(first).setMaxResults(pageSize);
        }

        return query.getResultList();
    }

    @Transient
    private void setParameters(FichaInscricao entidade, Query query) {
        if (entidade.getTipoParticipante() != null) {
            query.setParameter("tipoParticipante", entidade.getTipoParticipante().name().toLowerCase());
        }

        if (entidade.getMeioTransporte() != null) {
            query.setParameter("meioTransporte", entidade.getMeioTransporte().name().toLowerCase());
        }

        if (entidade.getTipoConvidado() != null) {
            query.setParameter("tipoConvidado", entidade.getTipoConvidado().name().toLowerCase());
        }

        if (entidade.getStatus() != null) {
            if (entidade.getStatus().equals(Status.PAGO) || entidade.getStatus().equals(Status.PAGO_SEM_FICHA)) {
                query.setParameter("status", entidade.getStatus().name().toLowerCase());
            }
        }

        if (entidade.getParticipante() != null) {

            Pessoa participante = entidade.getParticipante();

            if (participante.getNome() != null && !participante.getNome().isEmpty()) {
                query.setParameter("nomeParticipante", "%" + participante.getNome().toLowerCase() + "%");
            }

            if (participante.getEnderecoSimples() != null && !participante.getEnderecoSimples().isEmpty()) {
                query.setParameter("enderecoSimples", "%" + participante.getEnderecoSimples().toLowerCase() + "%");
            }
        }

        if (entidade.getClube() != null) {

            if (entidade.getClube().getId() != null) {
                query.setParameter("clubeId", entidade.getClube().getId());
            }
        }

        if (entidade.getConvidado() != null) {

            if (entidade.getConvidado().getNome() != null && !entidade.getConvidado().getNome().isEmpty()) {
                query.setParameter("nomeConvidado", "%" + entidade.getConvidado().getNome().toLowerCase() + "%");
            }
        }
    }

    private void setQuantidadeRegistros(String sql, Query query, FichaInscricao entidade) {

        String select = "SELECT count(f) ";

        query = getEntityManager().createQuery(select + sql);

        setParameters(entidade, query);

        quantidadeRegistrosResults = (Long) query.getSingleResult();
    }

    @Override
    public Long quantidadeRegistros() {
        return quantidadeRegistrosResults;
    }

    public List<Object[]> clubeMaisInscritosRotarianos() {
        String sql = "select distinct clube.nome, estado.sigla, count(fichainscricao) from fichainscricao, clube, estado "
                + "where fichainscricao.clube_id = clube.id and fichainscricao.tipoparticipante like 'ROTARIANO' "
                + "and clube.estado_id = estado.id "
                + "and fichainscricao.ativo = true "
                + "group by clube.nome, estado.sigla order by count(fichainscricao) desc";

        Query query = getEntityManager().createNativeQuery(sql);

        return query.getResultList();
    }

    public List<Object[]> clubeMaisInscritosCaravana() {
        String sql = "select distinct clube.nome, estado.sigla, count(pessoa) from fichainscricao, clube, estado, pessoa "
                + "where fichainscricao.clube_id = clube.id "
                + "and clube.estado_id = estado.id "
                + "and pessoa.nome is not null "
                + "and pessoa.nome not like '' "
                + "and (fichainscricao.participante_id = pessoa.id or fichainscricao.convidado_id = pessoa.id) "
                + "and fichainscricao.ativo = true "
                + "group by clube.nome, estado.sigla order by count(pessoa) desc";

        Query query = getEntityManager().createNativeQuery(sql).setMaxResults(10);

        return query.getResultList();
    }

    public Integer quantidadeDeInscritosParticipante(TipoParticipante tipo) {

        String sql = "SELECT count(f) FROM FichaInscricao f where f.tipoParticipante like '" + tipo.name() + "'";

        Query query = getEntityManager().createNativeQuery(sql);

        return ((Long) query.getSingleResult()).intValue();
    }

    public Integer quantidadeDeInscritosConvidados(TipoConvidado tipo) {

        String sql = "SELECT count(f) FROM FichaInscricao f where f.tipoConvidado like '" + tipo.name() + "'";

        Query query = getEntityManager().createNativeQuery(sql);

        return ((Long) query.getSingleResult()).intValue();
    }

    public List<FichaInscricao> fichas() {

        String sql = "select f from FichaInscricao f "
                + "where f.convidado.nome like '' and f.tipoConvidado like ''";

        Query query = getEntityManager().createQuery(sql);

        return query.getResultList();
    }
}
